package sdu.icat.pj.util;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.Collection;
import java.util.Map;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

public class DataUtil {

    private DataUtil() {
    }

    /**

     * 十进制字节数组转十六进制字符串

     * 

     * @param b

     * @return

     */
    public static final String byte2hex(byte[] b) { // 一个字节数，转成16进制字符串

	StringBuilder hs = new StringBuilder(b.length * 2);
	String stmp = "";
	for (int n = 0; n < b.length; n++) {
	    // 整数转成十六进制表示

	    stmp = Integer.toHexString(b[n] & 0XFF);
	    if (stmp.length() == 1)
		hs.append("0").append(stmp);
	    else
		hs.append(stmp);
	}
	return hs.toString(); // 转成大写

    }

    /**

     * 十六进制字符串转十进制字节数组

     * 

     * @param b

     * @return

     */
    public static final byte[] hex2byte(String hs) {
	byte[] b = hs.getBytes();
	if ((b.length % 2) != 0)
	    throw new IllegalArgumentException("长度不是偶数");
	byte[] b2 = new byte[b.length / 2];
	for (int n = 0; n < b.length; n += 2) {
	    String item = new String(b, n, 2);
	    // 两位一组，表示一个字节,把这样表示的16进制字符串，还原成一个十进制字节

	    b2[n / 2] = (byte) Integer.parseInt(item, 16);
	}
	return b2;
    }

    /**

     * 这个方法可以通过与某个类的class文件的相对路径来获取文件或目录的绝对路径。 通常在程序中很难定位某个相对路径，特别是在B/S应用中。

     * 通过这个方法，我们可以根据我们程序自身的类文件的位置来定位某个相对路径。

     * 比如：某个txt文件相对于程序的Test类文件的路径是../../resource/test.txt，

     * 那么使用本方法Path.getFullPathRelateClass("../../resource/test.txt",Test.class)

     * 得到的结果是txt文件的在系统中的绝对路径。

     * 

     * @param relatedPath

     *            相对路径

     * @param cls

     *            用来定位的类

     * @return 相对路径所对应的绝对路径

     * @throws IOException

     *             因为本方法将查询文件系统，所以可能抛出IO异常

     */
    public static final String getFullPathRelateClass(String relatedPath, Class<?> cls) {
	String path = null;
	if (relatedPath == null) {
	    throw new NullPointerException();
	}
	String clsPath = getPathFromClass(cls);
	File clsFile = new File(clsPath);
	String tempPath = clsFile.getParent() + File.separator + relatedPath;
	File file = new File(tempPath);
	try {
	    path = file.getCanonicalPath();
	} catch (IOException e) {
	    e.printStackTrace();
	}
	return path;
    }

    /**

     * 获取class文件所在绝对路径

     * 

     * @param cls

     * @return

     * @throws IOException

     */
    public static final String getPathFromClass(Class<?> cls) {
	String path = null;
	if (cls == null) {
	    throw new NullPointerException();
	}
	URL url = getClassLocationURL(cls);
	if (url != null) {
	    path = url.getPath();
	    if ("jar".equalsIgnoreCase(url.getProtocol())) {
		try {
		    path = new URL(path).getPath();
		} catch (MalformedURLException e) {
		}
		int location = path.indexOf("!/");
		if (location != -1) {
		    path = path.substring(0, location);
		}
	    }
	    File file = new File(path);
	    try {
		path = file.getCanonicalPath();
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	}
	return path;
    }

    /**

     * 判断对象是否Empty(null或元素为0)<br>

     * 实用于对如下对象做判断:String Collection及其子类 Map及其子类

     * 

     * @param pObj

     *            待检查对象

     * @return boolean 返回的布尔值

     */
    public static final boolean isEmpty(Object pObj) {
	if (pObj == null || "".equals(pObj))
	    return true;
	if (pObj instanceof String) {
	    if (((String) pObj).trim().length() == 0) {
		return true;
	    }
	} else if (pObj instanceof Collection<?>) {
	    if (((Collection<?>) pObj).size() == 0) {
		return true;
	    }
	} else if (pObj instanceof Map<?, ?>) {
	    if (((Map<?, ?>) pObj).size() == 0) {
		return true;
	    }
	}
	return false;
    }

    /**

     * 判断对象是否为NotEmpty(!null或元素>0)<br>

     * 实用于对如下对象做判断:String Collection及其子类 Map及其子类

     * 

     * @param pObj

     *            待检查对象

     * @return boolean 返回的布尔值

     */
    public static final boolean isNotEmpty(Object pObj) {
	if (pObj == null || "".equals(pObj))
	    return false;
	if (pObj instanceof String) {
	    if (((String) pObj).trim().length() == 0) {
		return false;
	    }
	} else if (pObj instanceof Collection<?>) {
	    if (((Collection<?>) pObj).size() == 0) {
		return false;
	    }
	} else if (pObj instanceof Map<?, ?>) {
	    if (((Map<?, ?>) pObj).size() == 0) {
		return false;
	    }
	}
	return true;
    }

    /**

     * JS输出含有\n的特殊处理

     * 

     * @param pStr

     * @return

     */
    public static final String replace4JsOutput(String pStr) {
	pStr = pStr.replace("\r\n", "<br/>&nbsp;&nbsp;");
	pStr = pStr.replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
	pStr = pStr.replace(" ", "&nbsp;");
	return pStr;
    }

    /**

     * 分别去空格

     * 

     * @param paramArray

     * @return

     */
    public static final String[] trim(String[] paramArray) {
	if (ArrayUtils.isEmpty(paramArray)) {
	    return paramArray;
	}
	String[] resultArray = new String[paramArray.length];
	for (int i = 0; i < paramArray.length; i++) {
	    String param = paramArray[i];
	    resultArray[i] = StringUtils.trim(param);
	}
	return resultArray;
    }

    /**

     * 获取类的class文件位置的URL

     * 

     * @param cls

     * @return

     */
    private static URL getClassLocationURL(final Class<?> cls) {
	if (cls == null)
	    throw new IllegalArgumentException("null input: cls");
	URL result = null;
	final String clsAsResource = cls.getName().replace('.', '/').concat(".class");
	final ProtectionDomain pd = cls.getProtectionDomain();
	if (pd != null) {
	    final CodeSource cs = pd.getCodeSource();
	    if (cs != null)
		result = cs.getLocation();
	    if (result != null) {
		if ("file".equals(result.getProtocol())) {
		    try {
			if (result.toExternalForm().endsWith(".jar") || result.toExternalForm().endsWith(".zip"))
			    result = new URL("jar:".concat(result.toExternalForm()).concat("!/").concat(clsAsResource));
			else if (new File(result.getFile()).isDirectory())
			    result = new URL(result, clsAsResource);
		    } catch (MalformedURLException ignore) {
		    }
		}
	    }
	}
	if (result == null) {
	    final ClassLoader clsLoader = cls.getClassLoader();
	    result = clsLoader != null ? clsLoader.getResource(clsAsResource)
		    : ClassLoader.getSystemResource(clsAsResource);
	}
	return result;
    }

    /** 初始化设置默认值 */
    public static final <K> K ifNull(K k, K defaultValue) {
	if (k == null) {
	    return defaultValue;
	}
	return k;
    }

}
